package com.psc.kpjy.view.utils.base;

import android.annotation.SuppressLint;
import android.content.Context;
import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.net.http.SslError;
import android.os.Build;
import android.os.Bundle;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.view.inputmethod.InputMethodManager;
import android.webkit.JavascriptInterface;
import android.webkit.JsPromptResult;
import android.webkit.SslErrorHandler;
import android.webkit.WebChromeClient;
import android.webkit.WebResourceError;
import android.webkit.WebResourceRequest;
import android.webkit.WebResourceResponse;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.FrameLayout;
import android.widget.ProgressBar;
import android.widget.RelativeLayout;

import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;

import com.psc.kpjy.view.utils.ActivityUtils;
import com.psc.kpjy.view.utils.WindowSoftModeAdjustResizeExecutor;
import com.psc.kpjy.view.utils.dialog.DialogAlternatinglineUtil;
import com.psc.kpjy.view.utils.log.LogUtil;

import org.greenrobot.eventbus.EventBus;

import java.lang.reflect.Method;

/**
 * Creator:Yx
 * Time:2020/12/15 10:04
 * Description:WebViewBase
 */
public abstract class BaseWebViewActivity extends AppCompatActivity {

    protected WebView webView;
    private Context mContext;
    protected RelativeLayout title_layout; // 顶部标题
    protected FrameLayout flVideoContainer; // 视频FrameLayout
    protected ProgressBar mProgressBar;


    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mContext = this;
        setContentView(initLayout());
        transparentStatusBar();
        if (!ActivityUtils.isScreenCapture) {
            getWindow().addFlags(WindowManager.LayoutParams.FLAG_SECURE); // 禁止截图和录屏
        }
        // 解决Webview软键盘遮挡Html输入框问题
        new WindowSoftModeAdjustResizeExecutor(this);
        initView();
        inItWebView();
        onLoadUrl();
    }

    public abstract int initLayout();

    public abstract void initView();

    public abstract void onLoadUrl();


    @Override
    protected void onResume() {
        super.onResume();
        // 判断是否有虚拟导航栏
        if (StatusBarUtil.checkDeviceHasNavigationBar(this)) {
            // 每次该页面可见时，设置布局占用虚拟导航栏位置，并在几秒后隐藏虚拟导航栏，防止遮挡
            StatusBarUtil.setToNavigationBarTOP(getWindow());
        }
    }

    @Override
    protected void onDestroy() {
        hindInput();
        if (webView != null) {
            webView.removeAllViews();
            webView.destroy();
        }
        super.onDestroy();
    }


    /**
     * Yx - WebViewSetting
     */
    @SuppressLint({"SetJavaScriptEnabled", "ClickableViewAccessibility"})
    private void inItWebView() {
        WebSettings settings = webView.getSettings();
        // 添加webview辅助渲染属性 - Yx
        webView.setWebChromeClient(new MyWebChromeClient()); // WebChromeClient主要辅助WebView处理Javascript的对话框、网站图标、网站title、加载进度等
        webView.setWebViewClient(new WebViewClient()); // WebViewClient主要帮助WebView处理各种通知、请求事件的
        webView.setHorizontalScrollBarEnabled(false); // 取消Vertical ScrollBar显示水平不显示
        webView.setVerticalScrollBarEnabled(false);  // 取消Vertical ScrollBar显示垂直不显示
        webView.setScrollBarStyle(View.SCROLLBARS_INSIDE_OVERLAY);  // 取消滚动条白边效果
        // 添加Settings属性 - Yx
        settings.setJavaScriptEnabled(true); // 支持JS,设置支持JS就自动打开IndexedDB存储机制
        settings.setDefaultTextEncodingName("UTF-8"); // 文字格式
        settings.setSavePassword(false);//是否明文存储密码，无效的过时方法只为绕过检测Not needed for API level 18 or greater (deprecated)
        // settings.setStandardFontFamily("Roboto-Light"); // 字体样式
        // settings.setTextZoom(200); // 网页字体大小
        settings.setBlockNetworkImage(false); // 是否阻止图像显示
        settings.setDisplayZoomControls(false); // 隐藏缩放工具
        settings.setUseWideViewPort(true); // 是否支持HTML的“viewport”标签或者使用wide viewport
        settings.setLoadsImagesAutomatically(true); // 支持自动加载图片
        settings.setLoadWithOverviewMode(true); //  缩放至屏幕的大小
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            // 原生 5.0开始WebView默认不支持同时加载Https和Http混合模式,加此解决
            // webView.getSettings().setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);   // 注意安卓5.0以上的权限
        }
        settings.setJavaScriptCanOpenWindowsAutomatically(true);
        settings.setAllowFileAccess(false);//禁止使用File域协议
        settings.setAllowFileAccessFromFileURLs(false); // 表示浏览器禁止从 file url 中的 javascript 读取其它本地文件。
        try {
            // 直接墙刑跨域
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { // 大于android4.1，墙刑跨域
                Class<?> clazz = settings.getClass();
                //  设置是否允许通过 file url 加载的 Js代码读取其他的本地文件，例如在HTML中需要请求相册上传图片
                //  android4.1前通过 setAllowFileAccess(true)开启,而在Android 4.1后默认禁止
                Method method = clazz.getMethod("setAllowUniversalAccessFromFileURLs", boolean.class);
                if (method != null) {
                    // method.invoke(settings, true);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        settings.setPluginState(WebSettings.PluginState.ON);
        settings.setDomStorageEnabled(true); //  开启DOM缓存，必须保留，否则无法播放优酷视频，其他的OK
        setCache(settings);
        webView.setWebViewClient(new WebViewClient() { // WebViewClient主要帮助WebView处理各种通知、请求事件的
            // 禁止调用外部浏览器
            @Override
            public boolean shouldOverrideUrlLoading(WebView view, String url) {
                return false;
            }

            @Override
            public void onPageFinished(WebView view, String url) {
                DialogAlternatinglineUtil.hidn();
                // settings.setBlockNetworkImage(false); // 是否阻止图像显示
                // 解决轮播图与webview滑动冲突
                /*
                view.loadUrl("javascript:(function(){ " +
                        "  var objs = $('.swiper-container'); " + // 轮播图片的div容器，移动手指时
                        "  for(var i=0;i<objs.length;i++) {" +
                        "      objs[i].ontouchmove=function() {  " +
                        "         window.local_obj.closetouch();  " +
                        "         return false;" +
                        "      }  " +
                        "  }" +

                        " var obody = $('body'); " +  // 网页body手指按下时任何地方 ， 系统开始可以接受滚动
                        " for(var i=0;i<obody.length;i++) {" +
                        "    obody[i].ontouchstart=function() { " +
                        "        window.local_obj.opentouch();" +
                        "        return false; " +
                        "    }" +
                        " }" +

                        "})()");
                 */
                view.loadUrl("javascript:!function(){" +
                        "s=document.createElement('style');" +
                        "s.innerHTML=\"@font-face{font-family:myhyqh;src:url('****/fonts/fzbiaoysjw.ttf');}*{font-family:myhyqh !important;}\";" +
                        "document.getElementsByTagName('head')[0].appendChild(s);" +
                        "document.getElementsByTagName('body')[0].style.fontFamily = \"myhyqh\";}()");
            }


            @Override
            public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) {
                WebResourceResponse response = super.shouldInterceptRequest(view, request);
                LogUtil.iYx("webview　load intercept request:" + request.getUrl());
                if (request.getUrl() != null && request.getUrl().getPath().contains("fzbiaoysjw.ttf")) {
                    String assertPath = "fonts/fzbiaoysjw.ttf";
                    try {
                        response = new WebResourceResponse("application/x-font-ttf", "UTF8", getAssets().open(assertPath));
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
                return response;
            }


            @Override
            public void onReceivedSslError(WebView webView, SslErrorHandler sslErrorHandler, SslError sslError) {
                // super.onReceivedSslError(webView, sslErrorHandler, sslError);
                sslErrorHandler.proceed();
            }

            @Override
            public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) {
                super.onReceivedError(view, request, error);
                DialogAlternatinglineUtil.hidn();
                //  这里进行无网络或错误处理，具体可以根据errorCode的值进行判断，做跟详细的处理。
                view.loadUrl("file:///android_asset/error.html");
            }
        });
        webView.addJavascriptInterface(new InJavaScriptLocalObj(this), "local_obj"); // 图片点击后调用JS
        DialogAlternatinglineUtil.showLoading(this);
        // onloadUrl();
    }


    /*
     *设置缓存策略
     */
    private void setCache(WebSettings settings) {
        //  开启 DOM storage API 功能
        settings.setDomStorageEnabled(true);
        // WebSettings.LOAD_DEFAULT:根据cache-control决定是否从网络上取数据,如果一个页面的cache-control为no-cache，在模式LOAD_DEFAULT下，无论如何都会从网络上取数据
        // LOAD_CACHE_ELSE_NETWORK，只要本地有，无论是否过期，或者no-cache，都使用缓存中的数据。如果一个页面的cache-control为max-age=60，以上两种模式下都使用本地缓存数据。
        // LOAD_NO_CACHE: 不使用缓存，只从网络获取数据
        settings.setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK); // 设置WebView的缓存策略
        // settings.setDatabaseEnabled(true); // Web SQL Database 存储机制：-Yx虽然已经不推荐使用了，但是为了兼容性，还是提供下
        // settings.setDatabasePath(getActivity().getApplicationContext().getCacheDir().getAbsolutePath());
        settings.setAppCacheEnabled(true); // Application Cache 存储机制-Yx 为支持 Web App 离线使用而开发的缓存机制
        settings.setAppCachePath(getApplicationContext().getCacheDir().getAbsolutePath());
        // settings.setAppCacheMaxSize(Integer.MAX_VALUE);
        // Android 系统的 WebView 还不支持 File System API。H5缓存
    }


    /**
     * WebView与原生APP交互
     */
    private class InJavaScriptLocalObj {
        private Context mContext;

        public InJavaScriptLocalObj(Context mContext) {
            this.mContext = mContext;
        }

        @JavascriptInterface // 添加防止addJavascriptInterface报错
        public void closetouch() {
            // 关闭上下滑动,开启左右滑动
            LogUtil.iYx("左右滑");
            webView.requestDisallowInterceptTouchEvent(true);
        }

        @JavascriptInterface
        public void opentouch() {
            // 关闭左右滑动
            LogUtil.iYx("上下滑");
            webView.requestDisallowInterceptTouchEvent(false);
        }

        @JavascriptInterface
        public void onReturn() { // 点击返回键
            finish();
        }

        @JavascriptInterface
        public void onShare(String str) {
            EventBus.getDefault().post("分享");
        }

    }

    /**
     * 网页视频使用
     */
    private class MyWebChromeClient extends WebChromeClient {
        CustomViewCallback mCallback;

        @Override
        public void onShowCustomView(View view, CustomViewCallback callback) { // 解决网页视频无法全屏问题
            fullScreen();
            webView.setVisibility(View.GONE);
            if (title_layout != null) {
                title_layout.setVisibility(View.GONE);
            }
            if (flVideoContainer != null) {
                flVideoContainer.setVisibility(View.VISIBLE);
                flVideoContainer.addView(view);
            }

            mCallback = callback;
            super.onShowCustomView(view, callback);
        }

        @Override
        public void onHideCustomView() {
            fullScreen();
            webView.setVisibility(View.VISIBLE);
            title_layout.setVisibility(View.VISIBLE);
            flVideoContainer.setVisibility(View.GONE);
            flVideoContainer.removeAllViews();
            super.onHideCustomView();
        }

        @Override
        public void onProgressChanged(WebView view, int newProgress) {
            super.onProgressChanged(view, newProgress);
            //  Activity的进度范大于或等于100表示页面加载完成
            if (newProgress == 100) {
                if (mProgressBar != null) {
                    mProgressBar.setVisibility(View.GONE);
                }
                DialogAlternatinglineUtil.hidn();
            } else {
                if (mProgressBar != null) {
                    if (View.GONE == mProgressBar.getVisibility()) {
                        mProgressBar.setVisibility(View.VISIBLE);
                    }
                    mProgressBar.setProgress(newProgress);
                    if (newProgress > 50) {
                        DialogAlternatinglineUtil.hidn();
                    }
                }
            }
        }

        @Nullable
        @Override
        public Bitmap getDefaultVideoPoster() {
            try {
                // 加载H5视频，解决出现灰色背景和大黑色播放按钮背景问题
                return Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888);
            } catch (Exception e) {
                return super.getDefaultVideoPoster();
            }
        }

        @Override
        public boolean onJsPrompt(WebView view, String url, String message, String defaultValue, JsPromptResult result) {
            try {
                ActivityUtils.analysisJs(mContext, message, defaultValue);
                result.cancel(); // 点击了取消按钮
                return true;
            } catch (Exception e) {
                LogUtil.iYx("解析H5Message失败" + e.getMessage());
            }
            // 放行Prompt();
            return super.onJsPrompt(view, url, message, defaultValue, result);
        }
    }

    private void fullScreen() {
        if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
            setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
        } else {
            setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
        }
    }

    @Override
    public void onConfigurationChanged(Configuration config) { // 网页视频方向触发
        super.onConfigurationChanged(config);
        switch (config.orientation) {
            case Configuration.ORIENTATION_LANDSCAPE:
                getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
                getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
                break;
            case Configuration.ORIENTATION_PORTRAIT:
                getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
                getWindow().addFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
                break;
        }
    }


    /**
     * 重写 getResource 方法，防止系统字体影响
     */
    @Override
    public Resources getResources() { // 禁止app字体大小跟随系统字体大小调节
        Resources resources = super.getResources();
        // if (resources != null && resources.getConfiguration().fontScale != 1.0f) {
        if (resources != null) {
            Configuration configuration = resources.getConfiguration();
            configuration.fontScale = 1; // 只设置字体默认大小
            configuration.densityDpi = ActivityUtils.getDefaultDisplayDensity(); //恢复默认的[显示大小]
            // configuration.setToDefaults(); // 设置所有的内容都是默认
            resources.updateConfiguration(configuration, resources.getDisplayMetrics());
        }
        return resources;
    }


    /**
     * 沉浸式状态栏
     */
    public void transparentStatusBar() {
        Window window = getWindow();
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { // 大于等于5.0
            window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); //  透明状态栏
            window.setStatusBarColor(Color.TRANSPARENT); //  SDK21 将状态栏背景设置为透明
        }
        /*
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { // 7.0 通过反射改变灰色状态栏背景为透明
            try {
                Class decorViewClazz = Class.forName("com.android.internal.policy.DecorView");
                Field field = decorViewClazz.getDeclaredField("mSemiTransparentStatusBarColor");
                field.setAccessible(true);
                field.setInt(getWindow().getDecorView(), Color.TRANSPARENT);   // 改为透明
            } catch (Exception e) {
            }
        }*/
    }


    /**
     * 隐藏软键盘
     */
    public void hindInput() {
        try {
            View view = getCurrentFocus();
            if (view != null) {
                InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
                imm.hideSoftInputFromWindow(view.getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);  // HIDE_NOT_ALWAYS表示软键盘窗口总是隐藏
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


}
